Skip to content

fix(deps): update dependency @simplewebauthn/server to v13 [security] - #9557

Open
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/npm-simplewebauthn-server-vulnerability
Open

fix(deps): update dependency @simplewebauthn/server to v13 [security]#9557
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/npm-simplewebauthn-server-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@simplewebauthn/server (source) ^10.0.0^13.0.0 age confidence

SimpleWebAuthn: Registration verification does not sufficiently ensure that attestation certificates chain to a trust anchor

GHSA-6hxq-p678-4hr2

More information

Details

Summary

validateCertificatePath() does not verify that an attestation's certificate chain actually terminates at a configured trust anchor. When walking the chain it stops at the first self-signed certificate it finds (which could be user-supplied), and exits early.

This happens before the configured Apple/Google/etc trust anchor (which is concatenated to the end of the chain) is reached.

A user can therefore register a credential and have the server accept it as if it were backed by a genuine Apple / Android SafetyNet / Yubikey / etc.

Details

packages/server/src/helpers/validateCertificatePath.ts:

The configured trust anchor is appended to the end of the untrusted chain (line 83):

const x5cWithTrustAnchor = x5cCertsParsed.concat([anchor]);

The walk then verifies each cert was signed by the next, but breaks on the first self-signed cert (lines 104–116):

if (issuer.subject === issuer.issuer) {
  // Root cert detected, make sure it signed itself
  const issuerSignedIssuer = await issuer.verify(
    { publicKey: issuer.publicKey, signatureOnly: true },
    WebCrypto,
  );
  if (!issuerSignedIssuer) {
    throw new InvalidSubjectAndIssuer();
  }
  break;   // <-- exits before the appended trust anchor is ever checked if user supplied self-signed cert comes first
}

The success condition is therefore "the certs form an internally-consistent chain ending in some self-signed cert" Rather than "the chain terminates at one of the configured trust anchors."

Exploit shape
attacker sends:  x5c = [ forgedLeaf (signed by attacker root),
                         attackerSelfSignedRoot ]

library builds:  [ forgedLeaf, attackerSelfSignedRoot, <configured Apple/Google/etc root> ]

walk:  forgedLeaf -> attackerSelfSignedRoot        (verifies, attacker controls both)
       attackerSelfSignedRoot is self-signed        -> break
       attackerSelfSignedRoot -> configured root    (NEVER CHECKED)

return true. The configured anchor never gets checked.

As far as observed, all attestation enforcement uses validateCertificatePath when using MDS etc.

Severity

  • CVSS Score: 2.0 / 10 (Low)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

MasterKale/SimpleWebAuthn (@​simplewebauthn/server)

v13.3.2

Compare Source

This update fixes a CVSS v4 Low (2.0) security vulnerability identified in
@​simplewebauthn/server. See the security advisory linked below for more information.

Changes:

  • [server] Fixed an issue with verifyRegistrationResponse() allowing a maliciously-crafted
    attestation statement's x5c to contain a self-signed "root certificate" instead of chaining back
    to an RP-specified trust anchor
    (GHSA-6hxq-p678-4hr2)

v13.3.1

Compare Source

Changes:

  • [server] Fixed an issue with verifyRegistrationResponse() failing to verify some Packed and
    SafetyNet statements (#​767)

v13.3.0

Compare Source

Changes:

  • [browser] startRegistration() and startAuthentication() will recognize punycode domains
    when trying to identify why an error occurred
    (#​750)
  • [server] A new verifyMDSBlob() helper method has been added to verify and extract metadata
    statements from FIDO MDS blobs. See
    the docs here
    for more info (#​752)

v13.2.3

Compare Source

Changes

  • [server] Dependencies have been updated to fix a "Cannot get schema" error that may occur
    when verifying responses after upgrading to v13.2.0+
    (#​747)

v13.2.2

Compare Source

Changes

v13.2.1

Compare Source

Changes:

  • [server] generateRegistrationOptions() will now correctly encoded the userID argument to
    base64url when it is an instance of Node's Buffer
    (#​724)

v13.2.0

Compare Source

Changes

  • [server] The return value from verifyRegistrationResponse() has been defined more strictly
    to communicate that registrationInfo will only ever be present if verified is true
    (#​715)
  • [server] verifyRegistrationResponse() can now verify attestations containing SHA256 hashes
    by using EC public keys with the P-384 curve
    (#​721)
  • [server] The Android SafetyNet "CTS profile match" system integrity check can now be disabled
    by setting attestationSafetyNetEnforceCTSCheck: false when calling
    verifyRegistrationResponse(). This check remains enforced by default
    (#​722)
  • [browser] [server] These libraries now have better support in Deno 2.2+ projects which use
    generic typing for Uint8Array via TypeScript 5.7.
    SimpleWebAuthn values of type Uint8Array_ are equivalent to Uint8Array in Deno 2.1 and
    earlier, and Uint8Array<ArrayBuffer> in Deno 2.2 and later.
    (#​717)

v13.1.2

Compare Source

Changes

  • [browser] [server] Exported the ResidentKeyRequirement type to help with type inference
    (#​704)

v13.1.1

Compare Source

Changes:

  • [server] "android-key" attestation statement verification has been modernized
    (#​675)
  • [server] More TPM manufacturers are recognized while verifying "tpm" attestation statements
    (#​673)

v13.1.0

Compare Source

Changes:

  • [server] The cross-fetch dependency has been removed from the project to silence in the
    console DeprecationWarning's about a "punycode" module
    (#​661)
  • [browser] startRegistration() and startAuthentication() will now warn about calls made
    using the pre-v11 call structure to encourage refactoring to use the current call structure, but
    still try to handle such calls the best they can
    (#​664)

v13.0.0

Compare Source

Hot on the heels of the last major release, v13 introduces support for registration hints! Refined
types and improved attestation trust anchor verification are also included. Last but not least, we
say goodbye to one of the project's packages for better docs and fewer dependencies to install. Read
on for more information, including refactor advice for dealing with the retirement of
@​simplewebauthn/types.

Changes:

  • [server] A new preferredAuthenticatorType argument can be set when calling
    generateRegistrationOptions() to generate options that encourage the browser to direct the user
    to register one of three types of authenticators: 'securityKey', 'localDevice', or
    'remoteDevice' (a.k.a. opinionated
    WebAuthn hints
    support) (#​653)
  • [browser] startRegistration() will recognize hints if specified in optionsJSON
    (#​652)
  • [server] Attestation verification now recognizes intermediate certificates as trust anchors
    (#​650)
  • [browser] [server] The types previously maintained in the types package are now included
    within the browser and server packages. See Breaking Changes below for more info
    (#​655)
Breaking Changes
@​typescript/types is being retired

Its types will now be included directly in @​simplewebauthn/browser and
@​simplewebauthn/server.

To refactor existing imports from /types, simply import them from /browser or /server
instead:

Before:

import type {
  AuthenticationResponseJSON,
  RegistrationResponseJSON,
  WebAuthnCredential,
} from '@simplewebauthn/types'; // <--

After:

import type {
  AuthenticationResponseJSON,
  RegistrationResponseJSON,
  WebAuthnCredential,
} from '@simplewebauthn/server'; // <--

[server] attestationType no longer accepts 'indirect'

The benefits of indirect attestation are too minimal to be useful for Relying Parties. In practice
it is almost never used over ignoring the concept completely with 'none' or needing to be
intentional and setting 'direct'.

RP's that have been specifying attestationType: 'indirect' when calling
generateRegistrationOptions() will need to refactor their code to either omit
attestationType (generateRegistrationOptions() will default to attestationType: 'none') or set
attestationType: 'direct' instead:

Before:

const options = await generateRegistrationOptions({
  // ...
  attestationType: 'indirect',
});

After:

const options = await generateRegistrationOptions({
  // ...
});

-or-

const options = await generateRegistrationOptions({
  // ...
  attestationType: 'direct',
});

v12.0.0

Compare Source

All SimpleWebAuthn packages are now available for installation from the
JavaScript Registry (JSR)! JSR is an "open-source package registry
for modern JavaScript and TypeScript" - you can read more about this new package registry and its
ESM-centric capabilities here.

All packages in v12.0.0 are functionally identical to v11.0.0! And JSR package hosting is in
addition to
existing package hosting on NPM. Nothing changes about package installation via
npm install. Read on for more information.

Packages
Changes
  • [browser] [server] [types] All packages can now be installed from JSR wherever JSR
    imports are supported (#​634)
  • [browser] Deno projects using frameworks like Fresh can now import and use
    @​simplewebauthn/browser (#​634)

To install from JSR, use npx jsr add @simplewebauthn/... or deno add jsr:@simplewebauthn/...
depending on which package manager is available.

Projects using npm for package management:
npx jsr add @simplewebauthn/browser
npx jsr add @simplewebauthn/server
npx jsr add @simplewebauthn/types
Projects using deno for package management:
deno add jsr:@simplewebauthn/browser
deno add jsr:@simplewebauthn/server
deno add jsr:@simplewebauthn/types
Projects using HTTPS modules via deno.land/x:

v12.0.0 officially deprecates importing SimpleWebAuthn from deno.land/x. See Breaking Changes
below for refactor guidance.

Breaking Changes

Importing SimpleWebAuthn packages from "https://deno.land/x/simplewebauthn/..." URLs is no longer
supported. Please use Deno's native support for JSR imports instead, available in projects running
Deno v1.42 and higher.

Before:

import { generateAuthenticationOptions } from 'https://deno.land/x/simplewebauthn/deno/server.ts';

After:

import { generateAuthenticationOptions } from 'jsr:@simplewebauthn/server';

Alternatively, use deno add to install these packages from
JSR:

# Deno v1.42 and higher
deno add jsr:@simplewebauthn/server
import { generateAuthenticationOptions } from '@simplewebauthn/server';

v11.0.0

Compare Source

Say hello to support for automatic passkey registration, support for valid conditional UI <input>
elements stashed away in web components, and to the new WebAuthnCredential type that modernizes
some logic within.

There are some breaking changes in this release! Please see Breaking Changes below for refactor
guidance.

Packages
Changes
  • [browser] [server] A new useAutoRegister argument has been added to startRegistration() to
    support attempts to automatically register passkeys for users who just completed non-passkey auth.
    verifyRegistrationResponse() has gained a new requireUserPresence option that can be set to
    false when verifying responses from startRegistration({ useAutoRegister: true, ... })
    (#​623)
  • [browser] A new verifyBrowserAutofillInput argument has been added to
    startAuthentication() to disable throwing an error when a correctly configured <input> element
    cannot be found (but perhaps a valid one is present in a web component shadow's DOM)
    (#​621)
  • [server] [types] The AuthenticatorDevice type has been renamed to WebAuthnCredential and
    has had its properties renamed. The return value out of verifyRegistrationResponse() and
    corresponding inputs into verifyAuthenticationResponse() have been updated accordingly. See
    Breaking Changes below for refactor guidance
    (#​625)
  • [server] verifyRegistrationResponse() now verifies that the authenticator data AAGUID
    matches the leaf cert's id-fido-gen-ce-aaguid extension AAGUID when it is present
    (#​609)
  • [server] TPM attestation verification recognizes the corrected TPM manufacturer identifier for
    IBM (#​610)
  • [server] Types for the defunct authenticator extensions uvm and dpk have been removed
    (#​611)
Breaking Changes
[browser] Positional arguments in startRegistration() and startAuthentication() have been replaced by a single object

Property names in the object match the names of the previously-positional arguments. To update
existing implementations, wrap existing options in an object with corresponding properties:

Before:

startRegistration(options);
startAuthentication(options, true);

After:

startRegistration({ optionsJSON: options });
startAuthentication({ optionsJSON: options, useBrowserAutofill: true });
[server] [types] The AuthenticatorDevice type has been renamed to WebAuthnCredential

AuthenticatorDevice.credentialID and AuthenticatorDevice.credentialPublicKey have been shortened
to WebAuthnCredential.id and WebAuthnCredential.publicKey respectively.

verifyRegistrationResponse() has been updated accordingly to return a new credential value of
type WebAuthnCredential. Update code that stores credentialID, credentialPublicKey, and
counter out of verifyRegistrationResponse() to store credential.id, credential.publicKey,
and credential.counter instead:

Before:

const { registrationInfo } = await verifyRegistrationResponse({...});

storeInDatabase(
  registrationInfo.credentialID,
  registrationInfo.credentialPublicKey,
  registrationInfo.counter,
  body.response.transports,
);

After:

const { registrationInfo } = await verifyRegistrationResponse({...});

storeInDatabase(
  registrationInfo.credential.id,
  registrationInfo.credential.publicKey,
  registrationInfo.credential.counter,
  registrationInfo.credential.transports,
);

Update calls to verifyAuthenticationResponse() to match the new credential argument that
replaces the authenticator argument:

Before:

import { AuthenticatorDevice } from '@simplewebauthn/types';

const authenticator: AuthenticatorDevice = {
  credentialID: ...,
  credentialPublicKey: ...,
  counter: 0,
  transports: [...],
};

const verification = await verifyAuthenticationResponse({
  // ...
  authenticator,
});

After:

import { WebAuthnCredential } from '@simplewebauthn/types';

const credential: WebAuthnCredential = {
  id: ...,
  publicKey: ...,
  counter: 0,
  transports: [...],
};

const verification = await verifyAuthenticationResponse({
  // ...
  credential,
});

v10.0.1

Compare Source

Packages
Changes
  • [server] isoCrypto.verify() now has better support for signature verification with ECC
    public keys using P-256, P-385, and P-521 curves
    (#​594, with thanks to @​nlordell)

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

Copilot AI lite review requested due to automatic review settings September 4, 2026 22:17
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

COMPARE TO master

Total Size Diff 📈 +2.51 KB

Diff by File
Name Diff
packages/core/package.json 0 Bytes
pnpm-lock.yaml 📈 +2.51 KB

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The dependency upgrade crosses multiple breaking versions and the current core WebAuthn code/tests still use v10-era SimpleWebAuthn API shapes that likely won’t typecheck/run against v13 without refactoring.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates @simplewebauthn/server in @logto/core from ^10.0.0 to ^13.0.0 (resolved to 13.3.3) to address the security advisory GHSA-6hxq-p678-4hr2 affecting registration attestation trust anchor verification.

Changes:

  • Bump @simplewebauthn/server dependency in packages/core to ^13.0.0.
  • Regenerate pnpm-lock.yaml to reflect the new SimpleWebAuthn version and its updated transitive dependency graph.
File summaries
File Description
packages/core/package.json Updates the direct dependency on @simplewebauthn/server to the v13 major line.
pnpm-lock.yaml Locks @simplewebauthn/server@13.3.3 and updates related transitive dependencies accordingly.
Review details

Files not reviewed (1)

  • pnpm-lock.yaml: Generated file
  • Files reviewed: 1/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

"@silverhand/essentials": "^2.9.1",
"@silverhand/slonik": "31.0.0-beta.2",
"@simplewebauthn/server": "^10.0.0",
"@simplewebauthn/server": "^13.0.0",
Copilot AI review requested due to automatic review settings September 8, 2026 00:03
@renovate
renovate Bot force-pushed the renovate/npm-simplewebauthn-server-vulnerability branch from cc82d35 to 9fa32eb Compare September 8, 2026 00:03
@github-actions github-actions Bot added size/xs and removed size/xs labels Sep 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

@simplewebauthn/server v13 introduces breaking API changes that are currently not accounted for in @logto/core, so the upgrade is likely to break typecheck/build until the affected call sites/imports are updated.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (1)

  • pnpm-lock.yaml: Generated file

Suppressed comments (1)

packages/core/package.json:53

  • Updating @simplewebauthn/server to v13 is a breaking change for this package: core/src/libraries/verification-helpers/webauthn.ts currently calls verifyAuthenticationResponse() with the legacy authenticator option (webauthn.ts:171). SimpleWebAuthn v11+ replaced this with credential, so this dependency bump will fail typecheck/build until the call site is refactored (e.g., map { credentialID, credentialPublicKey } to { id, publicKey }).
    "@logto/shared": "workspace:^",
    "@silverhand/essentials": "^2.9.1",
    "@silverhand/slonik": "31.0.0-beta.2",
    "@simplewebauthn/server": "^13.0.0",
    "@withtyped/client": "^0.8.8",
  • Files reviewed: 1/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines 49 to 53
"@logto/shared": "workspace:^",
"@silverhand/essentials": "^2.9.1",
"@silverhand/slonik": "31.0.0-beta.2",
"@simplewebauthn/server": "^10.0.0",
"@simplewebauthn/server": "^13.0.0",
"@withtyped/client": "^0.8.8",
Copilot AI review requested due to automatic review settings September 9, 2026 22:20
@renovate
renovate Bot force-pushed the renovate/npm-simplewebauthn-server-vulnerability branch from 9fa32eb to 347fd66 Compare September 9, 2026 22:20
@github-actions github-actions Bot added size/xs and removed size/xs labels Sep 9, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Migrate WebAuthn callers and fixtures and enforce the patched dependency minimum before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (1)

  • pnpm-lock.yaml: Generated file

Suppressed comments (3)

packages/core/package.json:52

  • v13 replaces the authenticator option passed to verifyAuthenticationResponse() with credential, and renames its fields to id and publicKey. src/libraries/verification-helpers/webauthn.ts still constructs the v10 object, which will fail the TypeScript check and cannot verify authentication after this dependency update; migrate that object and its related types.
    "@simplewebauthn/server": "^13.0.0",

packages/core/package.json:52

  • This major upgrade changes verifyRegistrationResponse() so registration data is returned under registrationInfo.credential (id, publicKey, and counter) rather than the removed credentialID/credentialPublicKey fields. The consumers in src/routes/experience/classes/verifications/web-authn-verification.ts and src/routes/interaction/verifications/mfa-payload-verification.ts still use the v10 shape, so real registrations will fail when isoBase64URL.fromBuffer() receives undefined; migrate both consumers and their test fixtures before merging.
    "@simplewebauthn/server": "^13.0.0",

packages/core/package.json:52

  • This major-version upgrade is not source-compatible with the existing WebAuthn integration. v13 renamed verifyAuthenticationResponse()'s authenticator option to credential (and its credentialID/credentialPublicKey fields to id/publicKey) and changed registration results to expose registrationInfo.credential; the callers in packages/core/src/libraries/verification-helpers/webauthn.ts, packages/core/src/routes/interaction/verifications/mfa-payload-verification.ts, and packages/core/src/routes/experience/classes/verifications/web-authn-verification.ts still use the v10 shapes. This will fail type-checking and, if emitted despite the errors, break authentication and persist undefined registration data. Update the callers and test fixtures together with this dependency change, or remain on a compatible version.
    "@simplewebauthn/server": "^13.0.0",
  • Files reviewed: 1/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

"@silverhand/essentials": "^2.9.1",
"@silverhand/slonik": "31.0.0-beta.2",
"@simplewebauthn/server": "^10.0.0",
"@simplewebauthn/server": "^13.0.0",
Copilot AI review requested due to automatic review settings September 10, 2026 18:18
@renovate
renovate Bot force-pushed the renovate/npm-simplewebauthn-server-vulnerability branch from 347fd66 to d4175e1 Compare September 10, 2026 18:18
@github-actions github-actions Bot added size/xs and removed size/xs labels Sep 10, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

@simplewebauthn/server v13 introduces breaking API changes, and the current core WebAuthn call sites/tests appear to still use the pre-v11 API shape, which is likely to break builds/tests after this bump.

Review details

Files not reviewed (1)

  • pnpm-lock.yaml: Generated file

Suppressed comments (1)

packages/core/package.json:52

  • Updating @simplewebauthn/server from v10 to v13 is a breaking change, but core’s WebAuthn integration still uses the pre-v11 API (e.g. verifyAuthenticationResponse options include authenticator, and registrationInfo is read as credentialID/credentialPublicKey), and there’s also a fragile type import from node_modules/@simplewebauthn/server/esm/deps.js. With v13 these are expected to change (e.g. credential replaces authenticator, and registrationInfo nests credential fields), so this version bump is likely to break build/tests unless the call sites and mocks are updated accordingly.
    "@simplewebauthn/server": "^13.0.0",
  • Files reviewed: 1/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

1 participant